package ClasesDeApoyo;

public class  Fecha implements Comparable<Fecha>
{
	
    // -----------------------------------------------------------------
    // Atributos
    // -----------------------------------------------------------------
	
	
	/**
	 * Atributo que modela un dia	
	 */

	private int dia;

	/**
	 * Atributo que modela la hora
	 */
	private int hora;
	/**
	 * Atributo que modela los minutos
	 */
	private int minuto;

	/**
	 * Atributo que modela si la fecha es de la siguiente semana
	 */
	private boolean siguienteSemana;

	
    // -----------------------------------------------------------------
    // Constructor
    // -----------------------------------------------------------------
	
	/**
	 * Metodo que crea una nueva clase fecha
	 * @param nDia el dia de la semana corresponiente a la documentacion del proyecto
	 * @param nHora la hora del dia 
	 * @param nMinuto el minuto de la hora
	 */
	public Fecha (int nDia, int nHora, int nMinuto, boolean sig)
	{
		dia = nDia;
		hora = nHora;
		minuto = nMinuto;
		siguienteSemana = sig;



	}


	
    // -----------------------------------------------------------------
    // Metodos
    // -----------------------------------------------------------------
	
	/**
	 * Metodo que compara fechas
	 * @param La fecha con la cua se va a comparar
	 * @return 
	 * 1 si la fecha de entrada corresponde a una fecha menor a esta fecha.
	 * 0 si las fechas son iguales
	 * -1 si la fecha de entrada corresponde a una fecha mayor a esta fecha
	 */
	public int compareTo(Fecha o) {


		if(o.isSiguienteSemana() && !siguienteSemana)
		{
			return -1;
		}
		else if(!o.isSiguienteSemana() && siguienteSemana)
		{
			return 1;
		}
		else if(o.getDia() > dia )
		{
			return -1;
		}
		else if(o.getDia() < dia)
		{
			return  1;

		}
		else if(o.getHora() > hora)
		{

			return  -1;
		}
		else if(o.getHora() < hora) 
		{
			return  1;
		}

		else if(o.getMinuto() > minuto)
		{
			return  -1;
		}
		else if(o.getMinuto() < minuto)
		{
			return   1;
		}
		else
		{
			return 0;
		}





	}




	/**
	 * Metodo que suma una cierta cantidad de minutos a la esta fecha
	 * <b>pre:</b> Todos los valores se encuentran inicializados <br>
     * <b>post:</b> La fecha ahora corresponde a la fecha anterior mas los minutos como parametro <br>
	 * @param minutos el numero de minutos a sumar
	 */
	public void sumar(int minutos)
	{
		if(minutos!= Integer.MAX_VALUE)
		{
			int diasNuevos = (minutos/(60*24));
			int horasNuevas = ((minutos - (diasNuevos*60*24))/60);
			int minutosNuevos = ((minutos - (diasNuevos*60*24) - (horasNuevas*60))%60);

			dia += diasNuevos;
			hora += horasNuevas;
			minuto += minutosNuevos;

			if(minuto > 59)
			{
				minuto = minuto%60;
				hora++;
			}

			if(hora > 23)
			{
				hora = hora%24;
				dia++;
			}

			if(dia > 6)
			{
				dia = dia%7;
				siguienteSemana = true;
			}
		}





	}
	
	/**
	 * Metodo que resta un cierto numeto de  minutos a esta fecha
	 * <b>pre:</b> Todos los valores se encuentran inicializados <br>
     * <b>post:</b> La fecha ahora corresponde a la fecha anterior menos los minutos como parametro <br>
	 * @param minutos el numero de minutos a restarle a la fecha
	 */
	public void restar(int minutos)
	{
		if(minutos!= Integer.MAX_VALUE)
		{
			int diasNuevos = (minutos/(60*24));
			int horasNuevas = ((minutos - (diasNuevos*60*24))/60);
			int minutosNuevos = ((minutos - (diasNuevos*60*24) - (horasNuevas*60))%60);

			dia -= diasNuevos;
			hora -= horasNuevas;
			minuto -= minutosNuevos;

			if(minuto < 0)
			{
				minuto = 60 + minuto;
				hora--;
			}

			if(hora < 0)
			{
				hora = 24 + hora;
				dia--;
			}

			if(dia < 0)
			{
				dia = 7 + dia;
				siguienteSemana = false;
			}
		}





	}
	
	
	/**
	 * Metodo que devuelve una resprentacion de String de la fecha
	 * @return Devuelve un string de la forma Dia HH:MM
	 */
	public String toString()
	{
		String[] dias = {"Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"};

		String hor = ""+hora;
		String min = "" + minuto;
		if(hora < 10)
		{
			hor = "0"+hora;
		}
		if(minuto < 10)
		{
			min = "0" + minuto;
		}




		return dias[dia] + " " + hor + ":" + min; 
	}
	
	/**
	 * Metodo que devuelve un String solo con la hora de la fecha ignorando el dia
	 * @return un string de la forma hh:mm
	 */
	public String toStringSoloHora()
	{
	

		String hor = ""+hora;
		String min = "" + minuto;
		if(hora < 10)
		{
			hor = "0"+hora;
		}
		if(minuto < 10)
		{
			min = "0" + minuto;
		}




		return  hor + ":" + min; 
	}
	

	
    // -----------------------------------------------------------------
    // Metodos Estaticos
    // -----------------------------------------------------------------
	


	/**
	 * Metodo que calcula la diferencia en minutos entre dos fechas
	 * @param fecha1 la fecha menor
	 * @param fecha2 la fecha mayor
	 * @return la dieferncia en minutos entre las dos fechas
	 */
	public static int darDiferenciaMinutos(Fecha fecha1, Fecha fecha2)
	{

		if(fecha2 == null || fecha1 == null)
		{
			return Integer.MAX_VALUE;
		}

		int temp =  ((fecha2.getDia()*60*24 + fecha2.getHora()*60 + fecha2.getMinuto()) - (fecha1.getDia()*60*24 + fecha1.getHora()*60 + fecha1.getMinuto()));

		if (fecha1.isSiguienteSemana() != fecha2.isSiguienteSemana())
		{


			if(temp > 0)
			{
				temp+= 24*60*7;
			}
			else
			{
				temp =  ((fecha2.getDia()*60*24 + fecha2.getHora()*60 + fecha2.getMinuto()) + ((6*24*60  - fecha1.getDia()*60*24) - (fecha1.getHora()*60) - fecha1.getMinuto()));
			}


		}

		return temp;
	}



    // -----------------------------------------------------------------
    // Getters and Setters
    // -----------------------------------------------------------------

	
	/**
	 * Metodo que devuelve el dia de la semana segun el estandar en la docuemntacion
	 * @return el dia de la semana
	 */
	public int getDia() 
	{
		return dia;
	}



	/**
	 * Metodo que dvuelve la hora del dia
	 * @return devuelve la hora del dia
	 */
	public int getHora() 
	{
		return hora;
	}


	/**
	 * Devuelve los minutos de esta horas
	 * @return lso minutos de la hora
	 */
	public int getMinuto() 
	{
		return minuto;
	}


	/**
	 * Metodo que devuelve si esta fecha corresponde a la siguiente semana
	 * @return un booleano respresentado si es o no de la siguiente semana
	 */
	public boolean isSiguienteSemana() 
	{
		return siguienteSemana;
	}



}
